package com.github.common.extend.demo.config.json.jaskson.precision;

import com.alibaba.fastjson.serializer.BeanContext;
import com.alibaba.fastjson.serializer.ContextValueFilter;
import com.github.common.extend.demo.config.json.DecimalPrecision;

import java.lang.reflect.Field;
import java.math.BigDecimal;

/**
 * @author wangjj7
 * @date 2024/3/27
 * @description
 */
public class DecimalPrecisionValueFilter implements ContextValueFilter {

    @Override
    public Object process(BeanContext context, Object object, String name, Object value) {
        if (value == null || context == null){
            return value;
        }
        // 获取字段上的注解(注意JsonField注解会自定义name)
        Field field = context.getField();
        //修复BUG：仅仅有setter/getter方法，但是未定义Field；会出现NPE
        if(field == null){
            return value;
        }
        DecimalPrecision fieldAnnotation = field.getAnnotation(DecimalPrecision.class);
        if (fieldAnnotation == null){
            return value;
        }
        int scale = fieldAnnotation.value();
        Class valueClass = value.getClass();

        if (String.class == valueClass){
            String str = (String) value;
            try {
                return new BigDecimal(Double.valueOf(str))
                        .setScale(scale ,fieldAnnotation.roundingMode())
                        .doubleValue();
            } catch (NumberFormatException e){
                return value;
            }
        }else if (Double.class == valueClass || double.class == valueClass){
            return (new BigDecimal((double) value)
                    .setScale(scale ,fieldAnnotation.roundingMode())
                    .doubleValue());
        }else if (Float.class == valueClass || float.class == valueClass){
            return (new BigDecimal((float) value)
                    .setScale(scale ,fieldAnnotation.roundingMode())
                    .floatValue());
        }else if (BigDecimal.class == valueClass){
            return (((BigDecimal) value)
                    .setScale(scale ,fieldAnnotation.roundingMode())
                    .floatValue());
        }
        return value;
    }

}
